package com.ibm.framework.exception.handler;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

import com.ibm.framework.exception.BaseException;
import com.ibm.framework.exception.model.ExceptionInfo;
import com.ibm.framework.exception.model.RawExceptionInfo;
import com.ibm.framework.exception.utils.CommonExceptionUtils;

/**
 * 功能描述： 异常信息提取器实现类
 * 
 * @author v_pinzhao
 * 
 */
public class DefaultLogExceptionInfoExtractor implements ExceptionInfoExtractor {
    /**
     * 抽取异常信息
     * 
     * @param rawEx 被抽取的异常信息
     * @return 异常信息
     */
    public ExceptionInfo extract(final RawExceptionInfo rawEx) {
        ExceptionInfo exceptionInfo = new ExceptionInfo();

        Throwable ex = rawEx.getThrowable();
        if (ex instanceof BaseException) {
            BaseException be = (BaseException) ex;
            exceptionInfo.setCode(be.getCode());
        }

        // set异常被拦截的时间
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String interceptTime = dateformat.format(new Date());
        exceptionInfo.setInterceptTime(interceptTime);

        /** set 被拦截的类 */
        exceptionInfo.setInterceptedClass(rawEx.getInterceptedClass());

        exceptionInfo.setInterceptedMethod(rawEx.getInterceptedInterface());
        /** set 被拦截方法的参数值 */
        exceptionInfo.setParameterValue(Arrays.toString(rawEx.getParameterValue()));

        exceptionInfo.setExceptionClass(ex.getClass().getName());
        exceptionInfo.setExceptionMessage(ex.getLocalizedMessage());

        /** get rootCause of exception得到根异常 */
        Throwable rootCause = CommonExceptionUtils.getMostSpecificCause(ex);
        /** 得到Stacktrace的elements */
        StackTraceElement[] elements = rootCause.getStackTrace();

        exceptionInfo.setRootException(rootCause.getClass().getName());
        exceptionInfo.setRootExceptionMsg(rootCause.getLocalizedMessage());
        /** 抛出根异常的类 */
        exceptionInfo.setRootCauseSpotClass(elements[0].getClassName());
        /** 抛出根异常的方法 */
        exceptionInfo.setRootCauseSpotMethod(elements[0].getMethodName());
        /** 抛出根异常的行号 */
        exceptionInfo.setRootCauseSpotLine("" + elements[0].getLineNumber());

        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        ex.printStackTrace(pw);

        exceptionInfo.setFullStackTrace(sw.toString());

        return exceptionInfo;
    }
}
